﻿#include "Direction.h"
#include <ctime>

/*
 * Function: Up
 * Summary: 构造函数，用于初始化成员变量dataChanged,numEachLine和combo
 * Input: void
 * Output: void
 */
Up::Up()
{
    dataChanged=0;
    numEachLine[4]={0};
    combo=0;
}

/*
 * Function: merge
 * Summary: 向上移动和合并棋盘中的数据
 * Input: arr为获取棋盘现有的数据
 * Output: 返回值为本次合并获得的分数
 */
int Up::merge(int** arr)
{
    dataChanged=0;
    int newScore=0;
    combo=0;

    //移动和合并数字
    for(int i=0;i<4;++i)
    {
        //numLoc表示数字将要存储的位次
        int numLoc=0;
        //前面是否有数字的合并标志
        bool isMerge=0;

        for(int j=0;j<4;++j)
        {
           //如果数字不为0，将数字依次移动存储
           if(arr[j][i]!=0)
           {
               if(j!=numLoc)
               {
                   arr[numLoc][i]=arr[j][i];
                   arr[j][i]=0;
                   dataChanged=1;
               }

               //从已经移动的第二个数开始，当合并标志为0时，判断其与前一个数是否相等，相等就合并
               //合并后将合并标志设为1，下一个数将合并标志设为0
               if(numLoc>0)
               {
                   if(isMerge==0)
                   {
                       if(arr[numLoc][i]==arr[numLoc-1][i])
                       {
                           arr[numLoc-1][i]=2*arr[numLoc-1][i];
                           arr[numLoc][i]=0;
                           isMerge=1;
                           ++combo;
                           dataChanged=1;
                           newScore=newScore+arr[numLoc-1][i];
                           continue;
                       }
                   }else {
                       isMerge=0;
                   }
               }
               ++numLoc;
           }
        }
        numEachLine[i]=numLoc;
    }

    return newScore;
}

/*
 * Function: generateNum
 * Summary: 依据空位产生一个随机数
 * Input: arr为获取棋盘的数据布局
 * Output: 返回值为随机数产生是否成功标志
 */
bool Up::generateNum(int** arr)
{
    srand((unsigned)time(NULL));

    //产生列的随机数
    int column=rand()%4;
    while(numEachLine[column]==4)
    {
        column=rand()%4;
    }

    //产生行的随机数
    int row=numEachLine[column]+(rand()%(4-numEachLine[column]));

    //2和4出现的概率为9：1
    int odds=rand()%10;
    if(odds<9)
    {
        arr[row][column]=2;
    }else {
        arr[row][column]=4;
    }

    return true;
}

/*
 * Function: getDataChanged
 * Summary: 获取成员变量dataChanged的值
 * Input: void
 * Output: 返回值为成员变量dataChanged的值
 */
bool Up::getDataChanged()
{
    return dataChanged;
}

/*
 * Function: getCombo
 * Summary: 获取成员变量combo的值
 * Input: void
 * Output: 返回值为成员变量combo的值
 */
int Up::getCombo()
{
    return combo;
}

/*
 * Function: Down
 * Summary: 构造函数，用于初始化成员变量dataChanged,numEachLine和combo
 * Input: void
 * Output: void
 */
Down::Down()
{
    dataChanged=0;
    numEachLine[4]={0};
    combo=0;
}

/*
 * Function: merge
 * Summary: 向下移动和合并棋盘中的数据
 * Input: arr为获取棋盘现有的数据
 * Output: 返回值为本次合并获得的分数
 */
int Down::merge(int** arr)
{
    dataChanged=0;
    int newScore=0;
    combo=0;

    //移动和合并数字
    for(int i=0;i<4;++i)
    {
        //numLoc表示数字将要存储的位次
        int numLoc=3;
        //前面是否有数字的合并标志
        bool isMerge=0;

        for(int j=3;j>=0;--j)
        {
           //如果数字不为0，将数字依次移动存储
           if(arr[j][i]!=0)
           {
               if(j!=numLoc)
               {
                   arr[numLoc][i]=arr[j][i];
                   arr[j][i]=0;
                   dataChanged=1;
               }

               //从已经移动的第二个数开始，当合并标志为0时，判断其与前一个数是否相等，相等就合并
               //合并后将合并标志设为1，下一个数将合并标志设为0
               if(numLoc!=3)
               {
                   if(isMerge==0)
                   {
                       if(arr[numLoc][i]==arr[numLoc+1][i])
                       {
                           arr[numLoc+1][i]=2*arr[numLoc+1][i];
                           arr[numLoc][i]=0;
                           isMerge=1;
                           ++combo;
                           dataChanged=1;
                           newScore=newScore+arr[numLoc+1][i];
                           continue;
                       }
                   }else {
                       isMerge=0;
                   }
               }
               --numLoc;
           }
        }
        numEachLine[i]=3-numLoc;
    }

    return newScore;
}

/*
 * Function: generateNum
 * Summary: 依据空位产生一个随机数
 * Input: arr为获取棋盘的数据布局
 * Output: 返回值为随机数产生是否成功标志
 */
bool Down::generateNum(int** arr)
{
    srand((unsigned)time(NULL));

    //产生列的随机数
    int column=rand()%4;
    while(numEachLine[column]==4)
    {
        column=rand()%4;
    }

    //产生行的随机数
    int row=rand()%(4-numEachLine[column]);

    //2和4出现的概率为9：1
    int odds=rand()%10;
    if(odds<9)
    {
        arr[row][column]=2;
    }else {
        arr[row][column]=4;
    }

    return true;
}

/*
 * Function: getDataChanged
 * Summary: 获取成员变量dataChanged的值
 * Input: void
 * Output: 返回值为成员变量dataChanged的值
 */
bool Down::getDataChanged()
{
    return dataChanged;
}

/*
 * Function: getCombo
 * Summary: 获取成员变量combo的值
 * Input: void
 * Output: 返回值为成员变量combo的值
 */
int Down::getCombo()
{
    return combo;
}

/*
 * Function: Left
 * Summary: 构造函数，用于初始化成员变量dataChanged,numEachLine和combo
 * Input: void
 * Output: void
 */
Left::Left()
{
    dataChanged=0;
    numEachLine[4]={0};
    combo=0;
}

/*
 * Function: merge
 * Summary: 向左移动和合并棋盘中的数据
 * Input: arr为获取棋盘现有的数据
 * Output: 返回值为本次合并获得的分数
 */
int Left::merge(int** arr)
{
    dataChanged=0;
    int newScore=0;
    combo=0;

    //移动和合并数字
    for(int i=0;i<4;++i)
    {
        //numLoc表示数字将要存储的位次
        int numLoc=0;
        //前面是否有数字的合并标志
        bool isMerge=0;

        for(int j=0;j<4;++j)
        {
           //如果数字不为0，将数字依次移动存储
           if(arr[i][j]!=0)
           {
               if(j!=numLoc)
               {
                   arr[i][numLoc]=arr[i][j];
                   arr[i][j]=0;
                   dataChanged=1;
               }

               //从已经移动的第二个数开始，当合并标志为0时，判断其与前一个数是否相等，相等就合并
               //合并后将合并标志设为1，下一个数将合并标志设为0
               if(numLoc>0)
               {
                   if(isMerge==0)
                   {
                       if(arr[i][numLoc]==arr[i][numLoc-1])
                       {
                           arr[i][numLoc-1]=2*arr[i][numLoc-1];
                           arr[i][numLoc]=0;
                           isMerge=1;
                           ++combo;
                           dataChanged=1;
                           newScore=newScore+arr[i][numLoc-1];
                           continue;
                       }
                   }else {
                       isMerge=0;
                   }
               }
               ++numLoc;
           }
        }
        numEachLine[i]=numLoc;
    }

    return newScore;
}

/*
 * Function: generateNum
 * Summary: 依据空位产生一个随机数
 * Input: arr为获取棋盘的数据布局
 * Output: 返回值为随机数产生是否成功标志
 */
bool Left::generateNum(int** arr)
{
    srand((unsigned)time(NULL));

    //产生行的随机数
    int row=rand()%4;
    while(numEachLine[row]==4)
    {
        row=rand()%4;
    }

    //产生列的随机数
    int column=numEachLine[row]+(rand()%(4-numEachLine[row]));

    //2和4出现的概率为9：1
    int odds=rand()%10;
    if(odds<9)
    {
        arr[row][column]=2;
    }else {
        arr[row][column]=4;
    }

    return true;
}

/*
 * Function: getDataChanged
 * Summary: 获取成员变量dataChanged的值
 * Input: void
 * Output: 返回值为成员变量dataChanged的值
 */
bool Left::getDataChanged()
{
    return dataChanged;
}

/*
 * Function: getCombo
 * Summary: 获取成员变量combo的值
 * Input: void
 * Output: 返回值为成员变量combo的值
 */
int Left::getCombo()
{
    return combo;
}

/*
 * Function: Right
 * Summary: 构造函数，用于初始化成员变量dataChanged,numEachLine和combo
 * Input: void
 * Output: void
 */
Right::Right()
{
    dataChanged=0;
    numEachLine[4]={0};
    combo=0;
}

/*
 * Function: merge
 * Summary: 向右移动和合并棋盘中的数据
 * Input: arr为获取棋盘现有的数据
 * Output: 返回值为本次合并获得的分数
 */
int Right::merge(int** arr)
{
    dataChanged=0;
    int newScore=0;
    combo=0;

    //移动和合并数字
    for(int i=0;i<4;++i)
    {
        //numLoc表示数字将要存储的位次
        int numLoc=3;
        //前面是否有数字的合并标志
        bool isMerge=0;

        for(int j=3;j>=0;--j)
        {
           //如果数字不为0，将数字依次移动存储
           if(arr[i][j]!=0)
           {
               if(j!=numLoc)
               {
                   arr[i][numLoc]=arr[i][j];
                   arr[i][j]=0;
                   dataChanged=1;
               }

               //从已经移动的第二个数开始，当合并标志为0时，判断其与前一个数是否相等，相等就合并
               //合并后将合并标志设为1，下一个数将合并标志设为0
               if(numLoc!=3)
               {
                   if(isMerge==0)
                   {
                       if(arr[i][numLoc]==arr[i][numLoc+1])
                       {
                           arr[i][numLoc+1]=2*arr[i][numLoc+1];
                           arr[i][numLoc]=0;
                           isMerge=1;
                           ++combo;
                           dataChanged=1;
                           newScore=newScore+arr[i][numLoc+1];
                           continue;
                       }
                   }else {
                       isMerge=0;
                   }
               }
               --numLoc;
           }
        }
        numEachLine[i]=3-numLoc;
    }

    return newScore;
}

/*
 * Function: generateNum
 * Summary: 依据空位产生一个随机数
 * Input: arr为获取棋盘的数据布局
 * Output: 返回值为随机数产生是否成功标志
 */
bool Right::generateNum(int** arr)
{
    srand((unsigned)time(NULL));

    //产生行的随机数
    int row=rand()%4;
    while(numEachLine[row]==4)
    {
        row=rand()%4;
    }

    //产生列的随机数
    int column=rand()%(4-numEachLine[row]);

    //2和4出现的概率为9：1
    int odds=rand()%10;
    if(odds<9)
    {
        arr[row][column]=2;
    }else {
        arr[row][column]=4;
    }

    return true;
}

/*
 * Function: getDataChanged
 * Summary: 获取成员变量dataChanged的值
 * Input: void
 * Output: 返回值为成员变量dataChanged的值
 */
bool Right::getDataChanged()
{
    return dataChanged;
}

/*
 * Function: getCombo
 * Summary: 获取成员变量combo的值
 * Input: void
 * Output: 返回值为成员变量combo的值
 */
int Right::getCombo()
{
    return combo;
}
